/*
 * @Author: 码农 2646995216@qq.com
 * @Date: 2025-03-02 23:53:02
 * @LastEditors: 码农 2646995216@qq.com
 * @LastEditTime: 2025-03-03 21:59:05
 * @FilePath: /pthread/ticket.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include<iostream>
#include<string>
#include<unistd.h>
#include <cstdio>
#include <cstring>
#include<vector>
#include<pthread.h>

using namespace std;
/*全局锁
class ThreadDate
{
public:
    ThreadDate(int num)
	{
		threadname="thread_"+to_string(num);
	}

public:
    string threadname;//线程的名字
};

int ticket=1000;//重票数
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;//创建锁，并且将其初始化

void* tickets(void* arg)
{
	ThreadDate *td = static_cast<ThreadDate*>(arg);//由于arg是指针类型，所以我们要用指针类型接收
    const char* name=td->threadname.c_str();

	while(true)
	{
		pthread_mutex_lock(&mutex);//加锁
		if(ticket>0)
		{
			usleep(1000);
			printf("%s running,get a ticket: %d\n",name,ticket);
            ticket--;
			pthread_mutex_unlock(&mutex);//解锁
		}
		else
		{
			pthread_mutex_unlock(&mutex);//解锁
			break;
		}
    }

}

int main()
{
	vector<pthread_t> tids;//存储线的tid
	vector<ThreadDate*> thread_dates;//存储线程，由于参数是(void*)的类型，所以我们要将参数设置为指针类型

	for(int i=1;i<=4;i++)
	{
		pthread_t tid;
        ThreadDate* date=new ThreadDate(i);//创建线程的名字
        thread_dates.push_back(date);
		pthread_create(&tid,NULL,tickets,(void*)thread_dates[i-1]);//创建成功返回线程的tid
		tids.push_back(tid);//存储tid，用于回收线程
	}

	for(auto thread:tids)
	{
		pthread_join(thread,nullptr);//回收线程
	}

	for (auto td : thread_dates)
    {
        delete td;//回收开辟的空间
    }

	return 0;
}
*/



//局部锁
class ThreadDate
{
public:
    ThreadDate(int num,pthread_mutex_t& mutex)
	:_mutex(mutex)
	{
		threadname="thread_"+to_string(num);
	}

public:
    string threadname;//线程的名字
	pthread_mutex_t& _mutex;
};

int ticket=1000;//重票数

void* tickets(void* arg)
{
	ThreadDate *td = static_cast<ThreadDate*>(arg);//由于arg是指针类型，所以我们要用指针类型接收
    const char* name=td->threadname.c_str();

	while(true)
	{
		pthread_mutex_lock(&td->_mutex);//加锁
		if(ticket>0)
		{
			usleep(1000);
			printf("%s running,get a ticket: %d\n",name,ticket);
            ticket--;
			pthread_mutex_unlock(&td->_mutex);//解锁
		}
		else
		{
			pthread_mutex_unlock(&td->_mutex);//解锁
			break;
		}
    }

}

int main()
{
	pthread_mutex_t mutex;//创建锁
	pthread_mutex_init(&mutex,nullptr);//初始化锁


	vector<pthread_t> tids;//存储线的tid
	vector<ThreadDate*> thread_dates;//存储线程，由于参数是(void*)的类型，所以我们要将参数设置为指针类型

	for(int i=1;i<=4;i++)
	{
		pthread_t tid;
        ThreadDate* date=new ThreadDate(i,mutex);//创建线程的名字
        thread_dates.push_back(date);
		pthread_create(&tid,NULL,tickets,(void*)thread_dates[i-1]);//创建成功返回线程的tid
		tids.push_back(tid);//存储tid，用于回收线程
	}

	for(auto thread:tids)
	{
		pthread_join(thread,nullptr);//回收线程
	}

	for (auto td : thread_dates)
    {
        delete td;//回收开辟的空间
    }

	pthread_mutex_destroy(&mutex);//销毁锁
	return 0;
}








/*void* tickets(void* arg)
{
	char *name= static_cast<char*>(arg);

	while(true)
	{
		if(ticket>0)
		{
			usleep(1000);
			printf("I am %s,get a ticket: %d\n",name,ticket);
            ticket--;
		}
		else
		{
			break;
		}
    }

}

int main()
{
	char* thread1="thread_1";
	char* thread2="thread_2";
	char* thread3="thread_3";
	char* thread4="thread_4";
	vector<char*> name;
    name.push_back(thread1);
	name.push_back(thread2);
	name.push_back(thread3);
	name.push_back(thread4);
    vector<pthread_t> tids;

	for(int i=1;i<=4;i++)
	{
		pthread_t tid;
		pthread_create(&tid,nullptr,tickets,(void*)name[i-1]);//创建成功返回线程的tid
		tids.push_back(tid);//存储tid，用于回收线程
	}

	for(auto thread:tids)
	{
		pthread_join(thread,nullptr);//回收线程
	}

	return 0;
}*/



/*class ThreadDate
{
public:
		ThreadDate(int num)
		{
			name="thread_"+to_string(num);
		}
public:
	string name;
};

int tickets=1000;

void* ticket(void* args)
{
	pthread_detach(pthread_self());
	ThreadDate* thread=static_cast<ThreadDate*>(args);
	const char* name=thread->name.c_str();
	while(true)
	{
		if(tickets>0)
		{
			usleep(1000);
			printf("I am a thraed,ticket:%d",tickets);
			tickets--;
		}

	}


}

int main()
{
	vector<ThreadDate*> thread;

	for(int i=1;i<=4;i++)
	{
		pthread_t tid;
		ThreadDate* Date=new ThreadDate(i);
		thread.push_back(Date);
		pthread_create(&tid,nullptr,ticket,(void*)thread[i-1]);
	}

	for(auto del:thread)
	{
		delete del;
	}

	return 0;
}
*/
